// main包：程序入口包，负责博客后端服务的初始化与启动
// 包含配置加载、数据库连接、路由注册等核心启动流程，是整个应用的入口点
// @title 博客系统API
// @version 1.0
// @BasePath /api
// @securityDefinitions.apikey BearerAuth
// @in header
// @name Authorization
// @description JWT认证令牌，格式：Bearer {token}
package main

import (
	"github.com/gin-gonic/gin" // Gin Web框架：用于构建HTTP服务、路由管理、中间件支持
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
	"go-blog/config"
	_ "go-blog/docs" // 确保导入路径与go.mod的module一致
	"go-blog/handler"
	"go-blog/middleware"
	"go-blog/model"
	"gorm.io/driver/mysql" // GORM的MySQL驱动：用于连接MySQL数据库
	"gorm.io/gorm"         // GORM框架：ORM工具，简化数据库操作
	"gorm.io/gorm/logger"  // GORM日志组件：用于配置数据库操作日志
	"log"                  // 标准库日志：用于输出服务启动信息、错误日志
	"os"                   // 标准库OS：用于获取标准输出流（配置GORM日志输出目标）
)

// main函数：程序入口点，执行服务初始化与启动流程
func main() {
	// 1. 初始化配置
	config.Init()

	// 2. 初始化数据库连接（MySQL）
	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags),
		logger.Config{
			LogLevel: logger.Info, // 显示SQL日志（生产环境可改为logger.Warn）
		},
	)

	db, err := gorm.Open(mysql.Open(config.Conf.DB.DSN), &gorm.Config{
		Logger: newLogger,
	})
	if err != nil {
		panic("数据库连接失败：" + err.Error())
	}

	// 3. 数据库迁移
	if err := db.AutoMigrate(&model.User{}, &model.Doc{}); err != nil {
		panic("数据库迁移失败：" + err.Error())
	}

	// 4. 初始化Gin引擎（开发环境建议用DebugMode）
	gin.SetMode(gin.DebugMode) // 开发阶段改为调试模式，便于排查问题
	r := gin.Default()

	// 5. 注册全局中间件
	r.Use(middleware.CORS())
	r.Use(middleware.GlobalErrorHandler())

	// 6. 注册Swagger UI路由
	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler,
		ginSwagger.URL("/swagger/doc.json"),
	))

	// 7. 注册API路由
	api := r.Group("/api")
	{
		// 公开接口组
		auth := api.Group("/auth")
		{
			auth.POST("/register", handler.Register(db))
			auth.POST("/login", handler.Login(db))
		}

		// 文档接口组（需JWT认证）
		doc := api.Group("/docs")
		doc.Use(middleware.JWTAuth())
		{
			doc.GET("", handler.GetDocs(db))
			doc.POST("", handler.CreateDoc(db))
			doc.PUT("/:id", handler.UpdateDoc(db))
			doc.DELETE("/:id", handler.DeleteDoc(db))
			doc.POST("/upload", handler.UploadDoc(db))
		}
	}

	// 8. 启动服务
	log.Println("后端服务启动：http://localhost:8081")
	if err := r.Run(":8081"); err != nil {
		panic("服务启动失败：" + err.Error())
	}
}
